package dsx.mongo;

import java.util.ArrayList;
import java.util.Date;

import com.fasterxml.jackson.databind.introspect.TypeResolutionContext;
import com.mongodb.BasicDBList;
import org.bson.Document;

import com.mongodb.BasicDBObject;

public class DataFetcher {

    // 字符串
    public static String getString(Object doc, String key) {
        return getString(doc, key, null);
    }

    public static String getString(Object doc, String key, String defaultValue) {
        String value = null;
        if (doc instanceof BasicDBObject) {
            value = getString((BasicDBObject) doc, key, defaultValue);
        } else if (doc instanceof Document) {
            value = getString((Document) doc, key, defaultValue);
        }

        if (value != null)
            return value;
        return defaultValue;

    }

    public static String getString(Document doc, String key) {
        return getString(doc, key, null);
    }

    public static String getString(Document doc, String key, String defaultValue) {
        String value = null;
        if (doc.containsKey(key))
            value = doc.getString(key);
        if (value != null)
            return value;
        return defaultValue;
    }

    public static String getString(BasicDBObject doc, String key) {
        return getString(doc, key, null);
    }

    public static String getString(BasicDBObject doc, String key, String defaultValue) {
        String value = null;
        if (doc.containsField(key))
            value = doc.getString(key);
        if (value != null)
            return value;
        return defaultValue;
    }

    // 日期
    public static Date getDate(Object doc, String key) {
        return getDate(doc, key, null);
    }

    public static Date getDate(Object doc, String key, Date defaultValue) {
        Date value = null;
        if (doc instanceof BasicDBObject) {
            value = getDate((BasicDBObject) doc, key, defaultValue);
        } else if (doc instanceof Document) {
            value = getDate((Document) doc, key, defaultValue);
        }
        if (value != null)
            return value;
        return defaultValue;
    }

    public static Date getDate(Document doc, String key) {
        return getDate(doc, key, null);
    }

    public static Date getDate(Document doc, String key, Date defaultValue) {
        Date value = null;
        if (doc.containsKey(key))
            value = doc.getDate(key);
        if (value != null)
            return value;
        return defaultValue;
    }

    public static Date getDate(BasicDBObject doc, String key) {
        return getDate(doc, key, null);
    }

    public static Date getDate(BasicDBObject doc, String key, Date defaultValue) {
        Date value = null;
        if (doc.containsField(key))
            value = doc.getDate(key);
        if (value != null)
            return value;
        return defaultValue;
    }

    // 32位整数
    public static int getInt(Object doc, String key) {
        return getInt(doc, key, -1);
    }

    public static int getInt(Object doc, String key, int defaultValue) {
        if (doc instanceof BasicDBObject) {
            return getInt((BasicDBObject) doc, key, defaultValue);
        } else if (doc instanceof Document) {
            return getInt((Document) doc, key, defaultValue);
        }
        return defaultValue;
    }

    public static int getInt(Document doc, String key) {
        return getInt(doc, key, -1);
    }

    public static int getInt(Document doc, String key, int defaultValue) {
        if (doc.containsKey(key))
            return parseInt(doc.get(key), defaultValue);
        return defaultValue;
    }

    public static int getInt(BasicDBObject doc, String key) {
        return getInt(doc, key, -1);
    }

    public static int getInt(BasicDBObject doc, String key, int defaultValue) {
        if (doc.containsField(key))
            return parseInt(doc.get(key), defaultValue);
        return defaultValue;
    }

    public static int parseInt(Object num, int defaultValue) {
        if (num == null)
            return defaultValue;
        else if (num instanceof Integer)
            return ((Integer) num).intValue();
        else if (num instanceof Long)
            return ((Long) num).intValue();
        else if (num instanceof Double)
            return ((Double) num).intValue();
        else if (num instanceof Float)
            return ((Float) num).intValue();
        else if (num instanceof String) {
            try {
                return Integer.parseInt((String) num);
            } catch (Exception ex) {
            }
        }
        return defaultValue;
    }

    // 64位整数
    public static long getLong(Object doc, String key) {
        return getInt(doc, key, -1);
    }

    public static long getLong(Object doc, String key, long defaultValue) {
        if (doc instanceof BasicDBObject) {
            return getLong((BasicDBObject) doc, key, defaultValue);
        } else if (doc instanceof Document) {
            return getLong((Document) doc, key, defaultValue);
        }
        return defaultValue;
    }

    public static long getLong(Document doc, String key) {
        return getLong(doc, key, -1);
    }

    public static long getLong(Document doc, String key, long defaultValue) {
        if (doc.containsKey(key))
            return parseLong(doc.get(key), defaultValue);
        return defaultValue;
    }

    public static long getLong(BasicDBObject doc, String key) {
        return getLong(doc, key, -1);
    }

    public static long getLong(BasicDBObject doc, String key, long defaultValue) {
        if (doc.containsField(key))
            return parseLong(doc.get(key), defaultValue);
        return defaultValue;
    }

    public static long parseLong(Object num, long defaultValue) {
        if (num == null)
            return defaultValue;
        else if (num instanceof Integer)
            return ((Integer) num).longValue();
        else if (num instanceof Long)
            return ((Long) num).longValue();
        else if (num instanceof Double)
            return ((Double) num).longValue();
        else if (num instanceof Float)
            return ((Float) num).longValue();
        else if (num instanceof String) {
            try {
                return Long.parseLong((String) num);
            } catch (Exception ex) {
            }
        }
        return defaultValue;
    }

    // double，float一律转成double
    public static double getDouble(Object doc, String key) {
        return getDouble(doc, key, -1);
    }

    public static double getDouble(Object doc, String key, double defaultValue) {
        if (doc instanceof BasicDBObject) {
            return getDouble((BasicDBObject) doc, key, defaultValue);
        } else if (doc instanceof Document) {
            return getDouble((Document) doc, key, defaultValue);
        }
        return defaultValue;
    }

    public static double getDouble(Document doc, String key) {
        return getDouble(doc, key, 0);
    }

    public static double getDouble(Document doc, String key, double defaultValue) {
        if (doc.containsKey(key))
            return parseDouble(doc.get(key), defaultValue);
        return defaultValue;
    }

    public static double getDouble(BasicDBObject doc, String key) {
        return getDouble(doc, key, 0);
    }

    public static double getDouble(BasicDBObject doc, String key, double defaultValue) {
        if (doc.containsField(key))
            return parseDouble(doc.get(key), defaultValue);
        return defaultValue;
    }

    public static double parseDouble(Object num, double defaultValue) {
        if (num == null)
            return defaultValue;
        else if (num instanceof Integer)
            return ((Integer) num).doubleValue();
        else if (num instanceof Long)
            return ((Long) num).doubleValue();
        else if (num instanceof Double)
            return ((Double) num).doubleValue();
        else if (num instanceof Float)
            return ((Float) num).doubleValue();
        else if (num instanceof String) {
            try {
                return Double.parseDouble((String) num);
            } catch (Exception ex) {
            }
        }
        return defaultValue;
    }

    // Object
    public static Object getObject(Object doc, String key) {
        if (doc instanceof BasicDBObject) {
            return getObject((BasicDBObject) doc, key);
        } else if (doc instanceof Document) {
            return getObject((Document) doc, key);
        } else {
            return null;
        }
    }

    public static Object getObject(Document doc, String key) {
        if (doc.containsKey(key))
            return doc.get(key);
        else
            return null;
    }

    public static Object getObject(BasicDBObject doc, String key) {
        if (doc.containsField(key))
            return doc.get(key);
        else
            return null;
    }

    public static ArrayList<String> getStringList(BasicDBObject doc, String key) {
        if (!doc.containsField(key))
            return null;
        BasicDBList dbList = (BasicDBList) doc.get(key);
        if (dbList == null)
            return null;
        ArrayList<String> stringList = new ArrayList<>();
        for (Object obj : dbList) {
            stringList.add((String) obj);
        }
        return stringList;
    }

}
